package dialer.client.web.controlador;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ValueChangeEvent;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DualListModel;

import dialer.ws.base.entity.Agent;
import dialer.ws.base.entity.CallAttribute;
import dialer.ws.base.entity.Calls;
import dialer.ws.base.entity.Campaign;
import dialer.ws.base.entity.Form;
import dialer.ws.base.exception.EntityException;
import dialer.ws.base.exception.EntityExistException;
import dialer.ws.base.exception.EntityNoFoundException;
import dialer.ws.business.service.CampaignService;
import dialer.ws.business.service.FormService;
import dialer.ws.common.util.FacesUtils;

@ManagedBean(name = "campaign")
@SessionScoped
public class CampaignController implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7698170705928958302L;

	private static final Log log = LogFactory.getLog(CampaignController.class);

	private String estado;
	private String nombre;
	private Date fchinicio;
	private Date fchfinal;
	private Integer intentos;
	private String script;

	private List<Campaign> listCampaign = new ArrayList<Campaign>();
	private List<String> listBase = new ArrayList<String>();
	private List<String> telefonos = new ArrayList<String>();

	private DualListModel<Form> listFormulario;

	private Campaign selectedCampaign;

	@ManagedProperty("#{campaignService}")
	private CampaignService campaignService;

	@ManagedProperty("#{formService}")
	private FormService formService;

	public CampaignController() {
		listFormulario = new DualListModel<Form>(new ArrayList<Form>(), new ArrayList<Form>());
	}

	@PostConstruct
	public void init() {
		listCampaign = campaignService.findAll();
		listFormulario.setSource(formService.getFormByState("A"));
		listFormulario.setTarget(new ArrayList<Form>());
	}

	@SuppressWarnings("unchecked")
	public void change(ValueChangeEvent event) {
		log.info("### change");
		DualListModel<Form> nuevo = (DualListModel<Form>) event.getNewValue();
		listFormulario.setSource(nuevo.getSource());
		listFormulario.setTarget(nuevo.getTarget());
	}

	public void actualizarLista() {
		log.info("### actualizarLista" + estado);
		if (estado != null && estado.equals("")) {
			listCampaign = campaignService.findAll();
		} else {
			listCampaign = campaignService.getCampaignByState(estado);
		}
	}

	public void activar() {
		log.info("### activar");
		if (!selectedCampaign.getEstado().equals("A")) {
			selectedCampaign.setEstado("A");
			try {
				campaignService.merge(selectedCampaign);
				FacesUtils.addInfoMessage("Satisfactorio", "se activo correctamente");
			} catch (EntityException e) {
				log.error("### ERROR: " + e);
				FacesUtils.addErrorMessage("Error", "error");
			}
		}
	}

	public void desactivar() {
		log.info("### desactivar");
		if (!selectedCampaign.getEstado().equals("I")) {
			selectedCampaign.setEstado("I");
			try {
				campaignService.merge(selectedCampaign);
				FacesUtils.addInfoMessage("Satisfactorio", "se desactivo correctamente");
			} catch (EntityException e) {
				log.error("### ERROR: " + e);
				FacesUtils.addErrorMessage("Error", "error");
			}
		}
	}

	public void guardar() {
		log.info("### guardar");
		if (listBase.isEmpty()) {
			FacesUtils.addWarnMessage("Advertencia", "debe de ingresar una base");
			return;
		}
		if (listFormulario.getTarget().isEmpty()) {
			FacesUtils.addWarnMessage("Advertencia", "debe seleccionar formulario");
			return;
		}

		Campaign c = new Campaign();
		c.setNombre(nombre);
		c.setFchInicio(fchinicio);
		c.setFchFinal(fchfinal);
		c.setHoraInicio(fchinicio);
		c.setHoraFinal(fchfinal);
		c.setIntentos(intentos);
		c.setContexto("from_internal");
		c.setCola("111");
		c.setCanales(23);
		c.setScript(script);
		c.setEstado("A");

		Agent agent = new Agent();
		agent.setId(6);

		List<Calls> listCall = new ArrayList<Calls>();
		for (String t : telefonos) {
			Calls call = new Calls();
			call.setAgent(agent);
			call.setCampaign(c);
			call.setTelefono(t);
			call.setIntentos(intentos);
			call.setDnc(0);
			call.setDatetime_originate(new Date());

			int orden = 1;
			List<CallAttribute> listCallAttribute = new ArrayList<CallAttribute>();
			for (String lb : listBase) {
				String[] aux = lb.split(",");
				if (t.equals(aux[0])) {
					CallAttribute ca = new CallAttribute();
					ca.setCall(call);
					ca.setColumna(aux[2]);
					ca.setValor(aux[1]);
					ca.setOrden(orden);
					listCallAttribute.add(ca);
					orden++;
				}
			}
			call.setListCallAttribute(listCallAttribute);

			listCall.add(call);
		}
		c.setListCall(listCall);

		List<Form> lf = new ArrayList<Form>();
		Form nf = null;
		for (Form f : listFormulario.getTarget()) {
			nf = new Form();
			nf = formService.findByPk(f.getId());
			lf.add(nf);
		}
		c.setListForm(lf);
		try {
			campaignService.persist(c);
			clear();
			FacesUtils.addInfoMessage("Satisfactorio", "se guardo correctamente");
		} catch (EntityExistException e) {
			log.error("### ERROR: " + e);
			FacesUtils.addErrorMessage("Error", "no se guardo correctamente");
		} catch (EntityException e) {
			log.error("### ERROR: " + e);
			FacesUtils.addErrorMessage("Error", "no se guardo correctamente");
		}
	}

	public void load() throws EntityNoFoundException {
		log.info("### load");
		if (selectedCampaign != null) {
			List<Form> listTarget = selectedCampaign.getListForm();
			List<Form> listSource = formService.getFormByState("A");

			for (Form f : listTarget) {
				Iterator<Form> itr = listSource.iterator();
				while (itr.hasNext()) {
					if (f.getId().equals(itr.next().getId())) {
						itr.remove();
						break;
					}
				}
			}

			listFormulario.setSource(listSource);
			listFormulario.setTarget(listTarget);
		}
	}

	public void editar() {
		log.info("### editar");

	}

	public void eliminar() {
		log.info("### eliminar");
	}

	public void handleFileUpload(FileUploadEvent event) {
		log.info("### handleFileUpload");
		try {
			InputStream is = event.getFile().getInputstream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			List<String> init = new ArrayList<String>();
			int numColumnas = 0;
			while (br.ready()) {
				String line = br.readLine().trim();
				String[] art = line.split(",");
				numColumnas = art.length;
				for (int i = 1; i < art.length; i++) {
					init.add(art[0] + "," + art[i]);
				}
			}

			String cabecera[] = new String[numColumnas - 1];
			int j = 0;
			for (String s : init) {
				if (s.split(",")[0].equals("")) {
					cabecera[j] = s.split(",")[1];
					j++;
				} else {
					break;
				}
			}

			Iterator<String> itr = init.iterator();
			int k = 0;
			while (itr.hasNext()) {
				@SuppressWarnings("unused")
				String element = itr.next();
				if (k < numColumnas - 1) {
					itr.remove();
				} else {
					break;
				}
				k++;
			}

			int x = 0;
			for (String s : init) {
				if (x == numColumnas - 1) {
					x = 0;
				}
				for (int y = 0; y < numColumnas - 1; y++) {
					if (y == x) {
						listBase.add(s + "," + cabecera[x]);
						x++;
						break;
					}
				}
			}

			HashSet<String> lista = new HashSet<String>();
			for (String lb : listBase) {
				log.info("### lista base " + lb);
				lista.add(lb.split(",")[0]);
			}

			Iterator<String> t = lista.iterator();
			while (t.hasNext()) {
				String element = t.next();
				telefonos.add(element);
			}

			FacesUtils.addInfoMessage("Satisfactorio", "base subido correctamente");
		} catch (IOException e) {
			log.error("### ERROR: " + e);
			FacesUtils.addErrorMessage("Error", "no se guardo correctamente");
		}
	}

	public void clear() {
		log.info("### clear");
		estado = "";
		nombre = "";
		fchinicio = new Date();
		fchfinal = new Date();
		intentos = 0;
		script = "";

		listCampaign = new ArrayList<Campaign>();
		listBase = new ArrayList<String>();
		telefonos = new ArrayList<String>();

		listFormulario = new DualListModel<Form>(new ArrayList<Form>(), new ArrayList<Form>());

		selectedCampaign = new Campaign();
	}

	public String getEstado() {
		return estado;
	}

	public void setEstado(String estado) {
		this.estado = estado;
	}

	public List<Campaign> getListCampaign() {
		return listCampaign;
	}

	public void setListCampaign(List<Campaign> listCampaign) {
		this.listCampaign = listCampaign;
	}

	public CampaignService getCampaignService() {
		return campaignService;
	}

	public void setCampaignService(CampaignService campaignService) {
		this.campaignService = campaignService;
	}

	public Campaign getSelectedCampaign() {
		return selectedCampaign;
	}

	public void setSelectedCampaign(Campaign selectedCampaign) {
		this.selectedCampaign = selectedCampaign;
	}

	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public Date getFchinicio() {
		return fchinicio;
	}

	public void setFchinicio(Date fchinicio) {
		this.fchinicio = fchinicio;
	}

	public Date getFchfinal() {
		return fchfinal;
	}

	public void setFchfinal(Date fchfinal) {
		this.fchfinal = fchfinal;
	}

	public Integer getIntentos() {
		return intentos;
	}

	public void setIntentos(Integer intentos) {
		this.intentos = intentos;
	}

	public String getScript() {
		return script;
	}

	public void setScript(String script) {
		this.script = script;
	}

	public void setListFormulario(DualListModel<Form> listFormulario) {
		this.listFormulario = listFormulario;
	}

	public DualListModel<Form> getListFormulario() {
		return listFormulario;
	}

	public FormService getFormService() {
		return formService;
	}

	public void setFormService(FormService formService) {
		this.formService = formService;
	}

	public List<String> getListBase() {
		return listBase;
	}

	public void setListBase(List<String> listBase) {
		this.listBase = listBase;
	}

	public List<String> getTelefonos() {
		return telefonos;
	}

	public void setTelefonos(List<String> telefonos) {
		this.telefonos = telefonos;
	}

}
